<template>
	<div
		:class="[
			'app-editor-container',
			'app-custom-dropdown-list',
			`app-custom-dropdown-list-${name}`,
		]"
	>
		<a-tree-select
			:value="curValue"
			:placeholder="placeholder"
			:tree-data="items"
			:disabled="disabled || readonly"
			:tree-checkable="multiple"
			:fieldNames="fieldNames"
			clearable
            :allowClear="true"
			@blur="onBlur"
			@focus="onFocus"
			@change="onChange"
		>
		</a-tree-select>
	</div>
</template>
<script lang="ts" setup>
import { computedNavData, deepCopy, IEvent, IParam, typeOf } from '@/core';
import { Http } from '@/http';
import { Ref } from 'vue';
import { customDropdownListProps } from './custom-dropdown-list';
import { useEditorTypeParams } from '@/hooks/use-editor';
interface EditorEmit {
	(name: 'component-action', value: IEvent<string>): void;
}
const props = defineProps(customDropdownListProps);
const emit = defineEmits<EditorEmit>();
// 类型校验
const { validateConfig, valueType, valueSeparator, objectNameField, objectIdField, objectValueField } = useEditorTypeParams();
validateConfig();

const items: Ref<IParam[]> = ref([]);

const fieldNames = computed(() => {
	const tempData = { label: 'label', value: 'value', options: 'children' };
	Object.assign(tempData, props.fieldMap);
	return tempData;
});

let curUrl: string = '';

let data: IParam[] = [];

watch(
	() => props.data,
	(newVal: any, oldVal: any) => {
        load();
	},
);

/**
 * 计算值
 */
const curValue = computed(() => {
    let value: any;
    let item: any = deepCopy(props.value as any);
    try {
        if (item) {
            const valueName: string = props.fieldMap['value'] ? props.fieldMap['value'] : 'value';
            if (props.multiple) {
                value = [];
                if (valueType == 'SIMPLES') {
                    value = item;
                } else if (valueType == 'OBJECTS') {
                    item.forEach((_item: any) => {
                        value.push(objectIdField ? _item[objectIdField] : _item[valueName]);
                    })
                } else {
                    value = item.split(valueSeparator ? valueSeparator : props.valueSeparator) || [];
                }
            } else {
                if (item && valueType == 'OBJECT') {
                    value = objectIdField ? item[objectIdField] : item[valueName];
                } else {
                    value = item;
                }
            }
        }
    } catch (error) {
        console.log(error);
    }
    return value
});

/**
 * 加载树数据
 */
const load = () => {
	const tempUrl = computeUrl();
	if (tempUrl && tempUrl != curUrl) {
        curUrl = tempUrl;
        data = []; 
        const _data = computedNavData(props.data, props.context, props.viewParams, props.filterParams);
		Http.getHttp()[props.method](tempUrl, _data).then((response: any) => {
				if (!response || !response.success) {
					App.getNotificationHelper().error(
						App.ts('common.generic.error', '错误'),
						App.ts('common.customdropdownlist.loadfail', '数据加载失败')
					);
					return;
				}
				if (response.data && response.data.length > 0) {
                    data = [...response.data];
					handleItems(response.data)					
				}
			})
			.catch((error: any) => {
				App.getNotificationHelper().error(
					App.ts('common.generic.error', '错误'),
					App.ts('common.customdropdownlist.loadfail', '数据加载失败')
				);
			});
	} else {
		App.getNotificationHelper().error(
				App.ts('common.generic.error', '错误'),
				App.ts('common.customdropdownlist.nourl', '无数据加载路径')
			);
	}
};

/**
 * 计算数据请求路径
 */
const computeUrl = () => {
	let url = props.url;
	const tempMap = props.urlMap ? Object.keys(props.urlMap) : [];
	if (url && tempMap && tempMap.length > 0) {
		tempMap.forEach((item: string) => {
			const tempValue = props.urlMap[item];
			let targetValue = null;
			if (props.data.hasOwnProperty(tempValue)) {
				targetValue = props.data[tempValue];
			} else if (props.context.hasOwnProperty(tempValue)) {
				targetValue = props.context[tempValue];
			} else if (props.viewParams.hasOwnProperty(tempValue)) {
				targetValue = props.viewParams[tempValue];
			}
			const str = '${' + item + '}';
			url = url.replaceAll(str, targetValue);
		});
	}
	return url;
};

/**
 * 构建树形数据结构
 */
const handleItems = (data: IParam[]) => {
	if (props.fieldMap) {
		const parentId = props.fieldMap['pid'];
		if (parentId) {
            const valueName: string = props.fieldMap['value'] ? props.fieldMap['value'] : 'value';
			items.value = handleChildren(data, parentId, valueName);
			return;
		}
	}
	items.value = data;
};

/**
 * 处理父子层级
 */
const handleChildren = (data: IParam[], parentId: string, curValue: string) => {
    let tempData: any[] = [];
    const setChildItems = (pValue: string, result: Array<IParam>, curItem: IParam)=>{
        result.forEach((item: IParam) =>{
            if(item[parentId] == pValue){
                let valueField: string = item[curValue];
                setChildItems(valueField, result, item);
                if(!curItem.children){
                    curItem.children = [];
                }
                curItem.children.push(item);
            }
        })
    }
	data.forEach((curItem: IParam) => {
        if (!curItem[parentId]) {
            let valueField: string = curItem[curValue];
            setChildItems(valueField, data, curItem);
            tempData.push(curItem);
        }
    })
	return tempData;
};

/**
 * 值改变
 */
const onChange = (select: any, option: any) => {
    const value = handleSelectData(select);
	emit('component-action', {
		name: props.name as string,
		action: 'valueChange',
		data: value,
	});
};

const handleSelectData = (select: any): any => {
    let result: any;
    const valueName: string = props.fieldMap['value'] ? props.fieldMap['value'] : 'value';
    const handleObjectParams = (item: IParam, selected: string): IParam => {
        const object: IParam = { [valueName]: selected };
        if (objectNameField) {
            Object.assign(object, {
                [objectNameField]: item[objectNameField]
            })
        }
        if (objectIdField) {
            Object.assign(object, {
                [objectIdField]: item[objectIdField]
            })
        }
        if (objectValueField) {
            Object.assign(object, {
                [objectValueField]: deepCopy(item)
            })
        }
        return object
    }
    if (typeOf(select) == 'array') {
        if (valueType == 'SIMPLES') {
            result = select;
        } else if (valueType == 'OBJECTS') {
            result = [];
            select.forEach((_select: string) => {
                const item = data.find((item: any) => item[valueName] == _select);
                if (item) {
                    result.push(handleObjectParams(item, _select));
                }
            })
        } else {
            result = select.join(valueSeparator ? valueSeparator : props.valueSeparator);
        }
        result = result.length > 0 ? result : null;
    } else {
        if (valueType == 'OBJECT') {
            const item = data.find((item: any) => item[valueName] == select);
            if (item) {
                result = handleObjectParams(item, select); 
            }
        } else {
            result = select;
        }
        result = result ? result : null
    }
    return result;
}

/**
 * 失去焦点
 */
const onBlur = () => {
	emit('component-action', {
		name: props.name as string,
		action: 'editorBlur',
		data: props.value,
	});
};

/**
 * 获取焦点
 */
const onFocus = () => {
	//重新加载数据并抛出聚焦事件
	emit('component-action', {
		name: props.name as string,
		action: 'editorFocus',
		data: props.value,
	});
};
</script>